package com.design.generic.keyed;

import com.design.generic.TestObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.pool2.KeyedPooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;

import java.util.Random;

/**
 * TestObject 工厂类
 */
@Slf4j
public class TestObjectKeyedFactory implements KeyedPooledObjectFactory<String, TestObject> {
    /**
     * /构造一个封装对象
     *
     * @return
     * @throws Exception
     */
    @Override
    public PooledObject<TestObject> makeObject(String key) throws Exception {
        DefaultPooledObject<TestObject> p = new DefaultPooledObject<>(new TestObject());
        log.debug("makeObject: {}, {}, {}", key, p.getObject().hashCode(), p.getState());
        return p;
    }

    /**
     * 销毁对象
     *
     * @param p
     * @throws Exception
     */
    @Override
    public void destroyObject(String key, PooledObject<TestObject> p) throws Exception {
        log.debug("destroyObject: {}, {}, {}", key, p.getObject().hashCode(), p.getState());
        // p.getObject().destroy();
    }

    /**
     * 验证对象是否可用
     *
     * @param p
     * @return
     */
    @Override
    public boolean validateObject(String key, PooledObject<TestObject> p) {
        log.debug("validateObject: {}, {}, {}", key, p.getObject().hashCode(), p.getState());
        try {
            Thread.sleep(new Random().nextInt(1000));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return p.getObject().isActive();
    }

    /**
     * 激活一个对象，使其可用用, 从池中取对象时会调用此方法
     *
     * @param p
     * @throws Exception
     */
    @Override
    public void activateObject(String key, PooledObject<TestObject> p) throws Exception {
        TestObject object = p.getObject();
        log.debug("activateObject: {}, {}", key, object.hashCode());
        Thread.sleep(10);
        object.setActive(true);
    }

    /**
     * 钝化一个对象,也可以理解为反初始化, 向池中返还对象时会调用此方法
     *
     * @param p
     * @throws Exception
     */
    @Override
    public void passivateObject(String key, PooledObject<TestObject> p) throws Exception {
        TestObject object = p.getObject();
        log.debug("passivateObject: {}", object.hashCode());
    }
}
